#coding=utf8

from mytoken import T, Token

class Scanner(object):

    #INTERFACE

    def __init__(self, file):
        """
        Сканер. Аргумент - файл-исходник. """
        self.Init(file)

    def Init(self, file):
        """
        Задает новый файл для сканирования и сбрасывает сканер в
        начальное состояние. """
        self.file = file
        self.text = ""
        self.ReadFromFile()
        self.Reset()

    def Reset(self, file= None):
        """
        Сбрасывает сканер в начальное состояние. Если задано имя файла,
        происходит считывание текста из него. """
        if not file:
            self.tokens = list()
            self.caretPosition = 0
        else:
            self.Init(file)

    def GetNextToken(self, caretShift= True):
        """
        Считывает следующий токен и возвращает объект Token. """
        if self.caretPosition in range(0, len(self.text)):
            token = self.FindToken()
            if token.Type() != T.NONE:
                if caretShift:
                    self.tokens.append(token)
                    self.caretPosition += len(token.Value())
                return token
            if caretShift:
                self.caretPosition += 1
            return Token(T.NONE)
        else:
            return Token(T.EOF)

    def GetNthPastToken(self, n):
        """
        Возвращает токен, считанный n токенов назад. N=0 для последнего
        считанного токена, N=-1 для следующего токена (каретка при этом не
        сдвигается) """
        if n >= 0:
            return self.tokens[-n - 1]
        else:
            return self.GetNextToken(False)

    def GetAllTokens(self):
        """
        Возвращает список токенов, обнаруженных в файле """
        token = self.GetNextToken()
        while token != T.EOF:
            self.tokens.append(token)
            token = self.GetNextToken()
        return self.tokens


    #PRIVATE METHODS

    def ReadFromFile(self):
        ch = self.file.read(1)
        prevCh = ""
        while ch != "":
            if not self.IsWhitespace(ch) or not self.IsWhitespace(prevCh):
                self.text += ch
                prevCh = ch
            ch = self.file.read(1)
        self.text = unicode(self.text)

    def IsWhitespace(self, ch):
        """
        Определяет, является ли символ незначимым """
        return ch.isspace() or ch == "\n"

    def FindToken(self):
        """
        Должен быть переопределен в классе-наследнике"""
        pass